﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using GTasksPlus.Model;
using RestSharp;

namespace GTasksPlus.Code
{
    public class TaskHelper
    {
        #region Clear Completed Tasks

        public static void ClearCompletedTasks(string id, Action<bool> response)
        {
            OAuthHelper.RefreshTokenCode(p => RetryClearCompletedTasks(new List<object> { id, response }));
        }

        private static void RetryClearCompletedTasks(IList<Object> obj)
        {
            const string message = "Some error while trying to clear completed tasks";
            var client = new RestClient { Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(GTasksSettings.AccessToken), Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.POST)
            {
                Resource = String.Format("https://www.googleapis.com/tasks/v1/lists/{0}/clear", obj[0])
            };
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    if (response.StatusCode == HttpStatusCode.NoContent)
                    {
                        var callback = obj[1] as Action<bool>;
                        if (callback != null) callback(true);
                    }
                    else
                        MessageBox.Show(message);
                }
                catch (Exception e)
                {
                    MessageBox.Show(message + "\n\n" + e.Message);
                }
            });
        }

        #endregion

        #region Delete

        public static void DeleteTask(TaskItem taskItem, Action<bool> response)
        {
            OAuthHelper.RefreshTokenCode(p => RetryDeleteTask(new List<object> { taskItem, response }));
        }

        private static void RetryDeleteTask(IList<Object> obj)
        {
            const string message = "Some error while trying to delete the task.";
            var client = new RestClient { Authenticator = new OAuth2UriQueryParameterAuthenticator(GTasksSettings.AccessToken), BaseUrl = ((TaskItem)obj[0]).selfLink, Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.DELETE);
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    if (response.StatusCode == HttpStatusCode.NoContent)
                    {
                        var callback = obj[1] as Action<bool>;
                        if (callback != null) callback(true);
                    }
                    else
                        MessageBox.Show(message);
                }
                catch (Exception e)
                {
                    MessageBox.Show(message + "\n\n" + e.Message);
                }
            });
        }

        #endregion

        #region Update

        public static void UpdateTask(TaskItem taskItem, Action<bool> response)
        {
            OAuthHelper.RefreshTokenCode(p => RetryUpdateTask(new List<object> { taskItem, response }));
        }

        private static void RetryUpdateTask(IList<object> obj)
        {
            const string message = "Some error while trying to update the task.";
            var client = new RestClient { Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(GTasksSettings.AccessToken), Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.PUT)
            {
                RequestFormat = DataFormat.Json,
                Resource = ((TaskItem)obj[0]).selfLink
            };
            request.AddBody(obj[0]);
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var callback = obj[1] as Action<bool>;
                        if (callback != null) callback(true);
                    }
                    else
                        MessageBox.Show(message);
                }
                catch (Exception e)
                {
                    MessageBox.Show(message + "\n\n" + e.Message);
                }
            });
        }

        #endregion

        #region Add

        public static void AddTask(TaskItem taskItem, Action<bool> response, string taskId)
        {
            OAuthHelper.RefreshTokenCode(p => RetryAddTask(new List<object> { taskItem, response, taskId }));
        }

        private static void RetryAddTask(IList<object> obj)
        {
            const string message = "Some error while trying to add the task.";
            var client = new RestClient { Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(GTasksSettings.AccessToken), Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.POST)
            {
                RequestFormat = DataFormat.Json,
                Resource = String.Format("https://www.googleapis.com/tasks/v1/lists/{0}/tasks", obj[2])
            };
            string dueDate = string.Empty;
            if(!string.IsNullOrEmpty(((TaskItem)obj[0]).due))
                dueDate = ",due: \"" + ((TaskItem)obj[0]).due + "\"";
            var ignored = "{title:\"" + ((TaskItem)obj[0]).title + "\",notes:\"" + ((TaskItem)obj[0]).notes + "\"" + dueDate + "}";
            request.AddParameter("application/json", ignored, ParameterType.RequestBody);
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        var callback = obj[1] as Action<bool>;
                        if (callback != null) callback(true);
                    }
                    else
                        MessageBox.Show(message);
                }
                catch (Exception e)
                {
                    MessageBox.Show(message + "\n\n" + e.Message);
                }
            });
        }

        #endregion

        #region Update a Task's Status

        public static void UpdateTaskStatus(string parentListId, string currentTaskId, bool isChecked, Action<bool> response)
        {
            OAuthHelper.RefreshTokenCode(p => RetryUpdateTaskStatus(new List<object> { parentListId, currentTaskId, isChecked, response }));
        }

        private static void RetryUpdateTaskStatus(IList<object> obj)
        {
            const string message = "Some error while trying to set the task status.";
            var client = new RestClient { Authenticator = new OAuth2AuthorizationRequestHeaderAuthenticator(GTasksSettings.AccessToken), Timeout = GTasksSettings.RequestTimeout };
            var request = new RestRequest(Method.PUT)
            {
                RequestFormat = DataFormat.Json,
                Resource = String.Format("https://www.googleapis.com/tasks/v1/lists/{0}/tasks/{1}", obj[0], obj[1])
            };
            var check = (bool)obj[2] ? "completed" : "needsAction";
            var ignored = "{id:\"" + obj[1] + "\",status:\"" + check + "\"}";
            request.AddParameter("application/json", ignored, ParameterType.RequestBody);
            client.ExecuteAsync(request, response =>
            {
                try
                {
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        if (obj[3] != null)
                        {
                            var callback = obj[3] as Action<bool>;
                            if (callback != null) callback(true);
                        }
                    }
                    else
                        MessageBox.Show(message);
                }
                catch (Exception e)
                {
                    MessageBox.Show(message + "\n\n" + e.Message);
                }
            });
        }

        #endregion
    }
}
